import IWxJsSDKNative, {IWxJsSDKConfig} from "./NativeInterface/IWxJsSDKNative";

import Share from './SDKPart/Share';
import WxJsSDKJsApiList from "./NativeInterface/WxJsSDKJsApiList";

const win = window;
let wx = (win as any).wx as IWxJsSDKNative;
delete (win as any).wx;

interface IWxJsSDKInitData {
    jsScript?: string;
    configParam: IWxJsSDKConfig;
}

export default class WxJsSDK {
    private readonly initPromise: Promise<any> | null = null;


    public config(conf: IWxJsSDKConfig) {
        return new Promise(function (resolve, reject) {
            wx.ready(resolve);
            wx.error(reject);
            wx.config(conf);
        });
    }

    public checkJsApi(apiList: WxJsSDKJsApiList[]) {
        return new Promise(function (resolve, reject) {
            wx.checkJsApi({
                jsApiList: apiList,
                success(res) {
                    resolve(res.checkResult);
                },
                fail(err) {
                    reject(err);
                },
            });
        });
    }


    private _share: Share | null = null;

    public get Share() {
        return this._share || (this._share = new Share(this.initPromise));
    }


    constructor(param: IWxJsSDKInitData) {
        if (!wx && !!param.jsScript) {
            this.initPromise = this.loadNativeSDK(param.jsScript).then(() => this.config(param.configParam));
        } else if (!!wx) {
            this.initPromise = this.config(param.configParam);
        } else {
            const errMsg = 'sdk.js needed(wx).';
            this.initPromise = new Promise((_, j) => j(errMsg));
            throw new TypeError(errMsg);
        }
    }

    private async loadNativeSDK(js: string) {
        await new Promise(function (resolve, reject) {
            const script = win.document.createElement('script');
            script.addEventListener('load', function () {
                win.setTimeout(function () {
                    wx = (win as any).wx as IWxJsSDKNative;
                    delete (win as any).wx;

                    resolve();
                }, 85);
            });
            script.addEventListener('error', function () {
                reject('load sdk.js failed.');
            });
            script.src = js;
        });
    }
}
